#include "class.h"
#include "common.h"
#include "string.h"
#include "obj_range.h"
#include "core.h"
#include "vm.h"
#include "utils.h"

DEFINE_BUFFER_METHOD(Method)

/**
 * @brief 判断a和b是否相等
*/
bool value_is_equal(Value a, Value b)
{
    if (a.value_type != b.value_type)
    {
        return false;
    }

    if (a.value_type == VT_NUM)
    {
        return a.num == b.num;
    }

    if (a.obj_header == b.obj_header)
    {
        return true;
    }

    if (a.obj_header->type != b.obj_header->type)
    {
        return false;
    }


    if (a.obj_header->type == OT_STRING)
    {
        ObjString *strA = VALUE_TO_OBJSTR(a);
        ObjString *strB = VALUE_TO_OBJSTR(b);
        return (strA->value.length == strB->value.length && memcmp(strA->value.start, strB->value.start, strA->value.length) == 0);
    }

    if (a.obj_header->type == OT_RANGE)
    {
        ObjRange *rgA = VALUE_TO_OBJRANGE(a);
        ObjRange *rgB = VALUE_TO_OBJRANGE(b);
        return (rgA->from == rgB->from && rgA->to ==rgB->to);
    }

    return false;

}

/**
 * @brief 新建裸类
*/
Class* new_raw_class(VM *vm, const char *name, uint32_t field_num)
{
    Class *class = ALLOCATE(vm, Class);

    init_objheader(vm, &class->obj_header, OT_CLASS, NULL);
    class->name = new_objString(vm, name, strlen(name));
    class->field_num = field_num;
    class->super_class = NULL;
    Method_buffer_init(&class->methods);

    return class;
}

/**
 * @brief 获得对象obj所属的类
*/
inline Class* get_class_of_obj(VM *vm, Value object)
{
    switch (object.value_type)
    {
        case VT_NULL:
            return vm->null_class;
        case VT_FALSE:
        case VT_TRUE:
            return vm->bool_class;
        case VT_NUM:
            return vm->num_class;
        case VT_OBJ:
            return VALUE_TO_OBJ(object)->class;
        default:
            NOT_REACHED()
    }
    return NULL;
}